package com.lin.sunnyweather

import android.content.Context
import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.ViewModelProvider
import com.lin.sunnyweather.ui.weather.ForecastViewModel
import com.lin.sunnyweather.ui.weather.LifeIndexViewModel
import com.lin.sunnyweather.ui.weather.NowViewModel
import com.lin.sunnyweather.utils.DataStoreUtils
import com.lin.sunnyweather.utils.ResUtils
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.forecast.view.*
import kotlinx.android.synthetic.main.forecast_item.view.*
import kotlinx.android.synthetic.main.life_index.*
import kotlinx.android.synthetic.main.now.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class MainActivity : AppCompatActivity() {

    lateinit var locationID: String

    lateinit var locationName: String

    private val lifeIndexViewModel =
        lazy { ViewModelProvider(this).get(LifeIndexViewModel::class.java) }

    private val nowViewModel = lazy { ViewModelProvider(this).get(NowViewModel::class.java) }

    private val forecastViewModel =
        lazy { ViewModelProvider(this).get(ForecastViewModel::class.java) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        navBtn.setOnClickListener {
            drawerLayout.openDrawer(GravityCompat.START)
        }

        val bitmap = BitmapFactory.decodeResource(resources, R.drawable.head)
        headView.setHeadBitmap(bitmap)

        nowViewModel.value.nowWeatherLiveData.observe(this, { result ->
            val nowWeather = result.getOrNull()
            nowWeather.let {
                if (it != null) {
                    it.apply {
                        weatherImageView.setImageResource(ResUtils.getWeatherIcon(icon))
                        weatherTextView.text = text
                        tempTextView.text = getString(R.string.temperature_format, temp)
                        humidityTextView.text = getString(R.string.humidity_format, humidity)
                    }
                } else {
                    Toast.makeText(this, "未查询到当前地区实时天气", Toast.LENGTH_SHORT).show()
                    result.exceptionOrNull()?.printStackTrace()
                }
            }
        })

        forecastViewModel.value.forecastLiveData.observe(this, { result ->
            val daily = result.getOrNull()
            if (daily != null) {
                forecast.forecastLayout.removeAllViews()
                val inflater =
                    getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
                for (item in daily) {
                    val view =
                        inflater.inflate(R.layout.forecast_item, forecast.forecastLayout, false)
                    view.apply {
                        item.apply {
                            dataInfo.text = fxDate
                            skyInfo.text = textDay
                            skyIcon.setImageResource(ResUtils.getWeatherIcon(iconDay))
                            temperatureInfo.text =
                                getString(R.string.temperature_range_format, tempMin, tempMax)
                        }
                    }
                    forecast.forecastLayout.addView(view)
                }
            } else {
                Toast.makeText(this, "未找到当地未来预报", Toast.LENGTH_SHORT).show()
                result.exceptionOrNull()?.printStackTrace()
            }
        })

        lifeIndexViewModel.value.lifeIndexLiveData.observe(this, { result ->
            val daily = result.getOrNull()
            if (daily != null) {
                daily.apply {
                    coldRiskText.text = first { it.type == "9" }.category
                    dressingText.text = first { it.type == "3" }.category
                    ultravioletText.text = first { it.type == "5" }.category
                    carWashingText.text = first { it.type == "2" }.category
                }
            } else {
                Toast.makeText(this, "未找到当地生活指数", Toast.LENGTH_SHORT).show()
                result.exceptionOrNull()?.printStackTrace()
            }
        })

        drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}

            override fun onDrawerOpened(drawerView: View) {}

            override fun onDrawerClosed(drawerView: View) {
                val inputMethodManager =
                    getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                inputMethodManager.hideSoftInputFromWindow(
                    drawerView.windowToken,
                    InputMethodManager.HIDE_NOT_ALWAYS
                )
            }

            override fun onDrawerStateChanged(newState: Int) {}
        })

        weatherSwipeRefreshLayout.setOnRefreshListener {
            refreshWeatherInfo()
            weatherSwipeRefreshLayout.isRefreshing = false
        }

        CoroutineScope(Dispatchers.IO).launch {
            locationID = DataStoreUtils.locationID.first()
            locationName = DataStoreUtils.locationName.first()
            withContext(Dispatchers.Main) {
                if (locationID.isEmpty()) {
                    locationTextView.text = getString(R.string.city_empty_title)
                    drawerLayout.openDrawer(GravityCompat.START)
                } else {
                    refreshWeatherInfo()
                }
            }
        }
    }

    /**
     * 刷新天气信息
     */
    fun refreshWeatherInfo() {
        if (locationID.isNotEmpty()) {
            locationTextView.text = locationName
            nowViewModel.value.searchNowWeather(locationID)
            forecastViewModel.value.searchForecast(locationID)
            lifeIndexViewModel.value.searchLifeIndex(locationID)
        }
    }
}